import Adapter from "./Adapter.js";
import interceptorManager from "./interceptorManager.js";
import utils from "./utils.js";
class Axios {
  constructor() {
    this.Adapter = new Adapter();
    this.interceptors = {
      request: new interceptorManager(),
      response: new interceptorManager(),
    };
  }
  #o2s = (obj) =>
    Object.keys(obj)
      .map((item) => `${item}=${obj[item]}`)
      .join("&");

  request(config) {
    // 等同于 axios 方法 axios()  ---> request();
    // 单纯的发送网络请求 ，先执行请求拦截器 发送网络请求，在执行返还拦截器
    let chain = [this.Adapter.xhr, undefined];
    // [requestResolve1,requestReject1,requestResolve2,requestReject2,this.Adapter.xhr,undefined,responseResolve1,responseReject1,responseResolve2,responseReject2]
    // 把 request 里的拦截器 添加到 chain之前
    this.interceptors.request.handles.forEach((item) => {
      chain.unshift(item.fulfilled, item.rejected);
    });
    this.interceptors.response.handles.forEach((item) => {
      chain.push(item.fulfilled, item.rejected);
    });
    console.log(chain);
    // 移除执行 chain ；
    let promise = Promise.resolve(config);
    // 一次性在队列里退出2个函数
    while (chain.length > 0) {
      promise = promise.then(chain.shift(), chain.shift());
    }
    return promise;
  }
}

let methodArr = ["get", "delete", "post", "patch", "put", "head"];
// 把这个方法添加到 Axios的原型对象里；
methodArr.forEach((method) => {
  // 第一类 2个参数 ： get 、delete head ；
  // axios.get(url,{配置})
  // 第二类 ： post put patch
  // axios.post(url,data,{配置项})；
  if (method == "get" || method == "delete" || method == "head") {
    // 通过 parmas来带参数
    Axios.prototype[method] = function (url, config) {
      config.url = url;
      config.method = method;
      return this.request(config);
    };
  } else {
    // 通过data来携带参数 ；
    Axios.prototype[method] = function (url, data, config) {
      config.method = method;
      config.url = url;
      config.data = data;
      return this.request(config);
    };
  }
});

// console.log(Axios.prototype);

function createInstance() {
  let instance = new Axios();
  // let request = instance.request;
  let request = instance.request.bind(instance);
  // 把 instance 混入到 request 函数里去
  // console.log(instance);
  utils.mergerConfig(request, instance);

  // 把 Axios.prototype 里的方法 混入到 request函数里 ；
  utils.mergerConfig(request, Axios.prototype, instance);
  console.dir(request);
  return request; // 返还出去 并没有执行；
}

let axios = createInstance();

// 1.对于返还对象的处理  2.对象get 形式 和post形式的参数 传递的处理；
export default axios;
